package com.ruoyi.web.controller.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.exception.base.XException;
import com.ruoyi.sj.domain.Order;
import com.ruoyi.sj.domain.TradingRecord;
import com.ruoyi.sj.mapper.MoneyMapper;
import com.ruoyi.sj.mapper.OrderMapper;
import com.ruoyi.sj.mapper.TradingRecordMapper;
import com.ruoyi.web.controller.app.intercepter.FilterAnnotation;
import com.ruoyi.web.controller.util.EncryptionUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.Date;

@Slf4j
@Component
@SuppressWarnings("ALL")
public class PayComponent {
    /*平台商号*/
    private final String platformNo = "0001565";
    /*证书密码*/
    private final String password = "200712";
    /*私钥证书*/
    private final String pfxPath = "certificate/private_key.pfx";
    /*公钥证书*/
    private final String cerPath = "certificate/public_key.cer";
    /*双乾证书*/
    private final String sqCerPath = "certificate/sq_sign.cer";
    /*下单接口*/
    // private final  String toPay = "https://qyfapi.95epay.com/api/api/pay/toPay";
    private final String toPay = "http://shoudan.95epay.com:9000/api/api/pay/toPay";

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private MoneyMapper moneyMapper;
    @Autowired
    private TradingRecordMapper tradingRecordMapper;

    /**
     * 系统下单
     *
     * @param order 下单信息
     * @return 下单结果
     */
    @Transactional(readOnly = false)
    public Order sendToPay(Order order) {
        // 修改订单状态为未支付
        order.setStatus(0);
        // 创建订单时间
        order.setCreateDate(new Date());
        order.setUpdateTime(new Date());
        if (!"balance".equals(order.getPayType())) {
            ToPayEntity entity = new ToPayEntity();
            // 支付渠道
            entity.setPayChannels(order.getPayType());
            // 支付金额
            entity.setPayAmount(order.getPayMoney());
            // 订单标题
            entity.setOrderSubject(order.getTitle());
            // 订单号码
            entity.setMerMerOrderNo(order.getSn());
            // 支付方式
            entity.setApiPayType("1");
            if (order.getType() == 1 ||
                    order.getType() == 3 ||
                    order.getType() == 4 ||
                    order.getType() == 5) {
                entity.setTradeType("1");
            } else if (order.getType() == 2) {
                entity.setTradeType("2");
            }
            // 请求支付信息
            PayResponseBody sendToPay = sendToPay(entity);
            order.setPayInfo(sendToPay.getResponseParameters());
        } else {
            // 判断支付密码
            if (order.getType() != 7) {
                String payPassword = orderMapper.selectPayPassword(order.getMemberId());
                if (StringUtils.isBlank(payPassword)) throw new XException("请先设置支付密码！");
                if (StringUtils.isBlank(order.getPayPassword())) throw new XException("请输入支付密码！");
                boolean validate = EncryptionUtils.validatePassword(order.getPayPassword(), payPassword);
                if (!validate) throw new XException("支付密码不正确！");
            }
            try {
                // 修改数据库中余额
                moneyMapper.insert(order.getMemberId());
                moneyMapper.subMoney(order.getMemberId(), order.getPayMoney());
                // 修改订单状态为已支付
                order.setStatus(1);
            } catch (Exception e) {
                throw new XException("账户余额不足！");
            }
        }
        //生成订单信息
        orderMapper.insertOrder(order);

        //生成交易明细
        TradingRecord tradingRecord = new TradingRecord();
        tradingRecord.setMemberId(order.getMemberId());
        tradingRecord.setRemark(order.getTitle());
        tradingRecord.setMoney(order.getPayMoney());
        tradingRecord.setType(order.getType().toString());
        tradingRecord.setCreateDate(new Date());
        tradingRecord.setPayNum(order.getSn());
        tradingRecordMapper.insertTradingRecord(tradingRecord);
        return order;
    }

    /**
     * 乾易付下单
     *
     * @param entity 下单信息
     * @return 下单结果
     */
    public PayResponseBody sendToPay(ToPayEntity entity) {
        entity.setSellerNo(StringUtils.isNotBlank(entity.getSellerNo()) ? entity.getSellerNo() : platformNo);
        entity.setRoutingFee(StringUtils.isNotBlank(entity.getRoutingFee()) ? entity.getRoutingFee() : "0");
        entity.setRoutingMerNo(StringUtils.isNotBlank(entity.getRoutingMerNo()) ? entity.getRoutingMerNo() : platformNo);
        entity.setCommissionFee(StringUtils.isNotBlank(entity.getCommissionFee()) ? entity.getCommissionFee() : "0");
        entity.setCommissionMerNo(StringUtils.isNotBlank(entity.getCommissionMerNo()) ? entity.getCommissionMerNo() : platformNo);
        return requestToPay(entity);
    }

    /**
     * 乾易付下单
     *
     * @param entity 下单信息
     * @return 下单结果
     */
    @FilterAnnotation(validator = true)
    public PayResponseBody requestToPay(ToPayEntity entity) {
        PayRequestBody requestBody = new PayRequestBody();
        requestBody.setMerNo(platformNo);
        requestBody.setApiContent(JSONObject.toJSONString(entity, SerializerFeature.WriteMapNullValue));
        requestSign(requestBody);
        // 请求网络
        OkHttpClient client = new OkHttpClient();
        RequestBody multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("merNo", requestBody.getMerNo())
                .addFormDataPart("version", requestBody.getVersion())
                .addFormDataPart("notifyUrl", requestBody.getNotifyUrl())
                .addFormDataPart("timestamp", requestBody.getTimestamp())
                .addFormDataPart("apiContent", requestBody.getApiContent())
                .addFormDataPart("signType", requestBody.getSignType())
                .addFormDataPart("sign", requestBody.getSign())
                .build();
        Request request = new Request.Builder().url(toPay)
                .addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)")
                .header("Content-Type", "text/html; charset=utf-8;")
                .post(multipartBody)//传参数、文件或者混合，改一下就行请求体就行
                .build();
        try {
            Response response = client.newCall(request).execute();
            ResponseBody body = response.body();
            if (body != null) {
                String result = body.string();//获取字符串数据
                if (result != null) {
                    PayResponseBody responseBody = JSON.parseObject(result, PayResponseBody.class);
                    log.info("requestBody = {}", requestBody);
                    log.info("responseBody = {}", responseBody);
                    return responseBody;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 请求签名
     *
     * @param entity 实体
     */
    private void requestSign(PayRequestBody entity) {
        StringBuilder builder = new StringBuilder();
        Class<?> clazz = entity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                try {
                    if (!"sign".equals(field.getName())) {
                        field.setAccessible(true);
                        if (StringUtils.isNotBlank(builder.toString())) {
                            builder.append("&");
                        }
                        builder.append(field.getName());
                        builder.append("=");
                        builder.append(field.get(entity));
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            String sign = CFCARAUtil.signMessageByP1(builder.toString(), pfxPath, password);
            entity.setSign(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 验签
     *
     * @param entity 参数
     * @return 结果
     */
    public boolean verifyMessageByP1(PayResponseBody entity) {
        StringBuilder builder = new StringBuilder();
        Class<?> clazz = entity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                try {
                    if (!"sign".equals(field.getName())) {
                        field.setAccessible(true);
                        if (StringUtils.isNotBlank(builder.toString())) {
                            builder.append("&");
                        }
                        builder.append(field.getName());
                        builder.append("=");
                        builder.append(field.get(entity));
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            return CFCARAUtil.verifyMessageByP1(builder.toString(), entity.getSign(), sqCerPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 成功除了
     *
     * @param order 订单
     */
    public void hanldeSuccess(String sn) {
        if (StringUtils.isNotBlank(sn)) {
            Order order = orderMapper.selectBySn(sn);
            hanldeSuccess(order);
        }
    }

    /**
     * 成功除了
     *
     * @param order 订单
     */
    public void hanldeSuccess(Order order) {
        if (order != null) {
            orderMapper.updateStatus(order.getSn());
            // 类型（0.转账，1.充值，2.提现，3.红包，4.金包，5.入群）
            Integer type = order.getType();
            if (type == 1) {
                orderMapper.updateRecharge(order.getGoodsId());
                moneyMapper.addMoney(order.getMemberId(), order.getPayMoney());
            } else if (type == 5) {
                try {
                    // 查询群主
                    String userId = orderMapper.selectGroupUser(order.getGoodsId());
                    orderMapper.updateApplication(order.getGoodsId());
                    moneyMapper.addMoney(userId, order.getPayMoney());
                } catch (Exception e) {
                    // e.printStackTrace();
                }
            } else if (type == 6||type == 7||type==0||type==3) {
                moneyMapper.addMoney(order.getGoodsId(), order.getPayMoney());
                //生成交易明细
                TradingRecord tradingRecord = new TradingRecord();
                tradingRecord.setMemberId(order.getGoodsId());
                tradingRecord.setRemark(order.getTitle());
                tradingRecord.setMoney(order.getPayMoney());
                tradingRecord.setType(order.getType().toString());
                tradingRecord.setCreateDate(new Date());
                tradingRecord.setPayNum(order.getSn());
                tradingRecordMapper.insertTradingRecord(tradingRecord);
            }
        }
    }
}
